<template>
  <div class="base-tree-node" :ref="`${node.id}_base_tree_node`">
    <div class="base-tree-node-content" :class="nodeContentClassNames" :style="{paddingLeft: `${16 * deep}px`}">
    
      <span 
        class="base-tree-node-arrow" 
        :class="{'base-tree-node-arrow-down': isExpand}" 
        @click="toggle"
      >
        <i class="iconfont icon-arrow-right" v-if="children.length > 0">
        </i>
      </span>
      
      <el-checkbox v-if="showCheckbox" :value="node.isChecked" @input="input"/>
      
      <span class="base-tree-node-name" @click.stop="transmit(node)">
        <tree-node-content/>
      </span>
      
    </div>
    
    <template v-if="isExpand">
      <base-tree-node 
        v-for="n in children" :key="n.id"
        :node="n" :selected="selected" :deep="deep + 1" :show-checkbox="showCheckbox"
        @node-click="transmit" @node-check="$emit('node-check', $event)"
        :node-render="nodeRender"/>  
    </template>
  </div>
</template>

<script>
export default {
  name: 'base-tree-node',
  props: {
    node: {
      type: Object,
      default: () => ({})
    },
    expand: {
      type: Boolean,
      default: false
    },
    selected: {
      type: Object,
      default: () => ({})
    },
    deep: {
      type: Number,
      default: 0
    },
    showCheckbox: {
      type: Boolean,
      default: false
    },
    nodeRender: Function,
    isDefaultExpand: {
      type: Boolean,
      default: false
    }
  },
  data(){
    return {
      isExpand: this.expand === true
    }
  },
  computed: {
    isNodeDisabledHover() {
      return Boolean(this.node?.disabledHover)
    },
    isSelected(){
      let isSelected = false;
      
      try {
        isSelected = this.node?.id == this.selected?.id;
      } catch (error) {
        console.warn('base-tree-node -> isSelected -> error', error);
      }
      
      return isSelected;
    },
    children() {
      return this.node?.children || []
    },
    nodeContentClassNames() {
      return {
        'base-tree-selected': this.isSelected,
        'base-tree-disabled-hover': this.isNodeDisabledHover,
      }
    }
  },
  watch: {
    selected(newValue) {
      this.$emit('selected-change')
    }
  },
  methods: {
    transmit(node){
      
      if (node.disabledClick) {
        return;
      }
      
      this.$emit('node-click', node);
    },
    toggle(){
      if(this.node.children.length == 0) return;
      
      this.isExpand = !this.isExpand;
    },
    input(value){
      this.$emit('node-check', {node: this.node, value})
    }
  },
  components: {
    TreeNodeContent: {
      name: 'tree-node-content',
      render(h){
        const parent = this.$parent
        const node = parent.node
        return (
          parent.nodeRender
            ? parent.nodeRender(h, parent.node)
            : <span>{node.name}</span>
        )
      }
    }
  }
}
</script>

<style lang="scss">
.base-tree-node{
  position: relative;
  font-size: 14px;
  margin: 2px 0;
}

.base-tree-node-content{
  display: flex;
  flex-flow: row nowrap;
  align-items: center;
  line-height: 28px;
  cursor: pointer;
  transition: background-color ease .15s,
              color ease .15s;

  &:hover,
  &.base-tree-selected{
    @include backgroundColorPrimaryLight9();
    @include fontColor();
    border-radius: 2px;
  }
}

.base-tree-disabled-hover {
  &:hover {
    background-color: unset !important;
    color: $text-color-primary !important;
  }
}

.base-tree-node-arrow{
  color: #97a8be;
  width: 20px;
  text-align: center;

  &.base-tree-node-arrow-down{
    transform: rotateZ(45deg)
  }

  i{
    font-size: 14px !important;
    font-style: normal !important;
    line-height: 28px !important;
    color: #ccc;
  }
}

.base-tree-node-name{
  flex: 1;  
  padding: 0 5px;
  white-space: nowrap;
  // text-overflow: ellipsis;
  // overflow: hidden;
}

.base-tree-node .el-checkbox{
  margin: 0;
}
</style>